home *** CD-ROM | disk | FTP | other *** search
/ Disc to the Future 2 / Disc to the Future Part II Programmer's Reference (Wayzata Technology)(6013)(1992).bin / MAC / THINKC / 5 / MACVOGL- / MATRIX.C < prev    next >
Text File  |  1992-07-19  |  7KB  |  340 lines

  1.  
  2. #include <stdio.h>
  3. #include "vogl.h"
  4.  
  5. static    Mstack    *msfree = (Mstack *)NULL;
  6.  
  7. void    _mapmsave();
  8.  
  9. /*
  10.  * copyvector
  11.  *
  12.  * Copy the 4 vector b to a.
  13.  *
  14.  */
  15. void
  16. copyvector(a, b)
  17.     register    Vector    a, b;
  18. {
  19.     a[0] = b[0];
  20.     a[1] = b[1];
  21.     a[2] = b[2];
  22.     a[3] = b[3];
  23. }
  24.  
  25. /*
  26.  * copymatrix
  27.  *
  28.  * Copy the  4 x 4 matrix b to the 4 x 4 matrix a
  29.  *
  30.  */
  31. void
  32. copymatrix(a, b)
  33.     register    Matrix    a, b;
  34. {
  35. #ifdef THINK_C
  36.     BlockMove ((Ptr)b, (Ptr)a, sizeof(Matrix));
  37. /*    register int    i;
  38.     register double    *pa, *pb;
  39.  
  40.     pa = (double *)a;
  41.     pb = (double *)b;
  42.     for(i = 0; i < 16; i++)
  43.         *(pa++) = *(pb++);*/
  44. #else
  45.     register int    i;
  46.     register double    *pa, *pb;
  47.  
  48.     pa = (double *)a;
  49.     pb = (double *)b;
  50.     for(i = 0; i < 16; i++)
  51.         *(pa++) = *(pb++);
  52. #endif
  53. }
  54.  
  55. /*
  56.  * copytranspose
  57.  *
  58.  *    copy the transpose of the 4 x 4 matrix b to the 4 x 4 matrix a.
  59.  */
  60. void
  61. copytranspose(a, b)
  62.     register Matrix    a, b;
  63. {
  64.     register int    i, j;
  65.  
  66.     for(i = 0; i < 4; i++)
  67.         for(j = 0; j < 4; j++)
  68.             a[i][j] = b[j][i];
  69. }
  70.  
  71. /*
  72.  * Retreive the top matrix on the stack and place it in m
  73.  */
  74. void
  75. getmatrix(m)
  76.     Matrix m;
  77. {
  78.     copymatrix(m, vdevice.transmat->m);
  79. }
  80.  
  81. /*
  82.  * pushmatrix
  83.  *
  84.  * Push the top matrix of the stack down, placing a copy
  85.  * of it on the top of the stack.
  86.  *
  87.  */
  88. void
  89. pushmatrix()
  90. {
  91.     Mstack    *tmpmat;
  92.     Token    *p;
  93.  
  94.     if (vdevice.inobject) {
  95.         p = newtokens(1);
  96.  
  97.         p->i = PUSHMATRIX;
  98.  
  99.         return;
  100.     }
  101.  
  102.     if (msfree != (Mstack *)NULL) {
  103.         tmpmat = vdevice.transmat;
  104.         vdevice.transmat = msfree;
  105.         msfree = msfree->back;
  106.         vdevice.transmat->back = tmpmat;
  107.         copymatrix(vdevice.transmat->m, tmpmat->m);
  108.     } else {
  109.         tmpmat = (Mstack *)vallocate(sizeof(Mstack));
  110.         tmpmat->back = vdevice.transmat;
  111.         copymatrix(tmpmat->m, vdevice.transmat->m);
  112.         vdevice.transmat = tmpmat;
  113.     }
  114. }
  115.  
  116. /*
  117.  * popmatrix
  118.  *
  119.  * Pop the top matrix from the stack.
  120.  *
  121.  */
  122. void
  123. popmatrix()
  124. {
  125.     Token    *p;
  126.     Mstack    *oldtop;
  127.  
  128.     if (vdevice.inobject) {
  129.         p = newtokens(1);
  130.  
  131.         p->i = POPMATRIX;
  132.  
  133.         return;
  134.     }
  135.  
  136.     if (vdevice.transmat->back == (Mstack *)NULL)
  137.         verror("popmatrix: matrix stack empty");
  138.     else {
  139.         oldtop = vdevice.transmat;
  140.         vdevice.transmat = vdevice.transmat->back;
  141.         oldtop->back = msfree;
  142.         msfree = oldtop;
  143.     }
  144.  
  145.     vdevice.cpVvalid = 0;    /* may have changed mapping from world to device coords */
  146. }
  147.  
  148. /*
  149.  * loadmatrix
  150.  *
  151.  * Replace the top matrix on the stack
  152.  *
  153.  */
  154. void
  155. loadmatrix(mat)
  156.     Matrix    mat;
  157. {
  158.     register int    i;
  159.     register double    *cm, *mp;
  160.     Token        *p;
  161.  
  162.     if (!vdevice.initialised)
  163.         verror("loadmatrix: vogl not initialised");
  164.  
  165.     if (vdevice.inobject) {
  166.         p = newtokens(17);
  167.  
  168.         p[0].i = LOADMATRIX;
  169.         cm = (double *)mat;
  170.         for (i = 0; i < 16; i++)
  171.             (++p)->f = *cm++;
  172.  
  173.         return;
  174.     }
  175.  
  176.     cm = (double *)vdevice.transmat->m;
  177.     mp = (double *)mat;
  178. #ifdef THINK_C
  179.     BlockMove ((Ptr)mp, (Ptr)cm, sizeof(Matrix));
  180. /*    for (i = 0; i < 16; i++)
  181.         *cm++ = *mp++;*/
  182. #else
  183.     for (i = 0; i < 16; i++)
  184.         *cm++ = *mp++;
  185. #endif
  186.  
  187.     /*
  188.      * Save the untransformed matrix for the reverse mapping.
  189.      */
  190.  
  191.     _mapmsave(mat);
  192.  
  193.     vdevice.cpVvalid = 0;        /* may have changed mapping from world to device coords */
  194. }
  195.  
  196. /*
  197.  * mult4x4
  198.  *
  199.  *    multiply 4 x 4 matrices b and c assigning them into a. Readers are
  200.  * reminded that speed can be important here.
  201.  *
  202.  */
  203. void
  204. mult4x4(a, b, c)
  205.     register Matrix    a, b, c;
  206. {
  207.     a[0][0] = b[0][0] * c[0][0] + b[0][1] * c[1][0] + b[0][2] * c[2][0] + b[0][3] * c[3][0];
  208.     a[0][1] = b[0][0] * c[0][1] + b[0][1] * c[1][1] + b[0][2] * c[2][1] + b[0][3] * c[3][1];
  209.     a[0][2] = b[0][0] * c[0][2] + b[0][1] * c[1][2] + b[0][2] * c[2][2] + b[0][3] * c[3][2];
  210.     a[0][3] = b[0][0] * c[0][3] + b[0][1] * c[1][3] + b[0][2] * c[2][3] + b[0][3] * c[3][3];
  211.  
  212.     a[1][0] = b[1][0] * c[0][0] + b[1][1] * c[1][0] + b[1][2] * c[2][0] + b[1][3] * c[3][0];
  213.     a[1][1] = b[1][0] * c[0][1] + b[1][1] * c[1][1] + b[1][2] * c[2][1] + b[1][3] * c[3][1];
  214.     a[1][2] = b[1][0] * c[0][2] + b[1][1] * c[1][2] + b[1][2] * c[2][2] + b[1][3] * c[3][2];
  215.     a[1][3] = b[1][0] * c[0][3] + b[1][1] * c[1][3] + b[1][2] * c[2][3] + b[1][3] * c[3][3];
  216.  
  217.     a[2][0] = b[2][0] * c[0][0] + b[2][1] * c[1][0] + b[2][2] * c[2][0] + b[2][3] * c[3][0];
  218.     a[2][1] = b[2][0] * c[0][1] + b[2][1] * c[1][1] + b[2][2] * c[2][1] + b[2][3] * c[3][1];
  219.     a[2][2] = b[2][0] * c[0][2] + b[2][1] * c[1][2] + b[2][2] * c[2][2] + b[2][3] * c[3][2];
  220.     a[2][3] = b[2][0] * c[0][3] + b[2][1] * c[1][3] + b[2][2] * c[2][3] + b[2][3] * c[3][3];
  221.  
  222.     a[3][0] = b[3][0] * c[0][0] + b[3][1] * c[1][0] + b[3][2] * c[2][0] + b[3][3] * c[3][0];
  223.     a[3][1] = b[3][0] * c[0][1] + b[3][1] * c[1][1] + b[3][2] * c[2][1] + b[3][3] * c[3][1];
  224.     a[3][2] = b[3][0] * c[0][2] + b[3][1] * c[1][2] + b[3][2] * c[2][2] + b[3][3] * c[3][2];
  225.     a[3][3] = b[3][0] * c[0][3] + b[3][1] * c[1][3] + b[3][2] * c[2][3] + b[3][3] * c[3][3];
  226. }
  227.  
  228. /*
  229.  * multmatrix
  230.  *
  231.  * Premultipy the top matrix on the stack by "mat"
  232.  *
  233.  */
  234. void
  235. multmatrix(mat)
  236.     Matrix    mat;
  237. {
  238.     Matrix    prod;
  239.     double    *m;
  240.     Token    *p;
  241.     int    i;
  242.  
  243.     if (vdevice.inobject) {
  244.         p = newtokens(17);
  245.  
  246.         p[0].i = MULTMATRIX;
  247.         m = (double *)mat;
  248.         for (i = 0; i < 16; i++)
  249.             (++p)->f = *m++;
  250.  
  251.         return;
  252.     }
  253.  
  254.     mult4x4(prod, mat, vdevice.transmat->m);
  255.     loadmatrix(prod);
  256. }
  257.  
  258. /*
  259.  * identmatrix
  260.  *
  261.  * Return a 4 x 4 identity matrix
  262.  *
  263.  */
  264. void
  265. identmatrix(a)
  266.     Matrix      a;
  267. {
  268.     register double    *p;
  269.  
  270.     for (p = (double *)a; p != (double *)a + 16; p++)
  271.         *p = 0;
  272.  
  273.     a[0][0] = a[1][1] = a[2][2] = a[3][3] = 1;
  274. }
  275.  
  276. /*
  277.  * multvector
  278.  *
  279.  * Multiply the vector a and the matrix b to form v. Need it to be snappy again.
  280.  * 
  281.  */
  282. void
  283. multvector(v, a, b)
  284.     register    Vector    v, a;
  285.     register    Matrix    b;
  286. {
  287.     v[0] = a[0] * b[0][0] + a[1] * b[1][0] + a[2] * b[2][0] + a[3] * b[3][0];
  288.     v[1] = a[0] * b[0][1] + a[1] * b[1][1] + a[2] * b[2][1] + a[3] * b[3][1];
  289.     v[2] = a[0] * b[0][2] + a[1] * b[1][2] + a[2] * b[2][2] + a[3] * b[3][2];
  290.     v[3] = a[0] * b[0][3] + a[1] * b[1][3] + a[2] * b[2][3] + a[3] * b[3][3];
  291. }
  292.  
  293. /*
  294.  * premultvector
  295.  *
  296.  * PreMultiply the vector a and the matrix b to form v. 
  297.  * Need it to be snappy again.
  298.  * 
  299.  */
  300. void
  301. premultvector(v, a, b)
  302.     Vector    v, a;
  303.     Matrix    b;
  304. {
  305.     v[0] = a[0] * b[0][0] + a[1] * b[0][1] + a[2] * b[0][2] + a[3] * b[0][3];
  306.     v[1] = a[0] * b[1][0] + a[1] * b[1][1] + a[2] * b[1][2] + a[3] * b[1][3];
  307.     v[2] = a[0] * b[2][0] + a[1] * b[2][1] + a[2] * b[2][2] + a[3] * b[2][3];
  308.     v[3] = a[0] * b[3][0] + a[1] * b[3][1] + a[2] * b[3][2] + a[3] * b[3][3];
  309. }
  310.  
  311. #ifdef DEBUG 
  312.  
  313. /*
  314.  * printmat
  315.  *
  316.  *    print s and then dump matrix m. Useful for debugging, you get
  317.  * sick of typing in the print loop otherwise.
  318.  */
  319. printmat(s, m)
  320.     char    *s;
  321.     Matrix    m;
  322. {
  323.     int    i, j;
  324.  
  325.     printf("%s\n", s);
  326.     for (i = 0; i < 4; i++) {
  327.         for (j = 0; j < 4; j++)
  328.             printf("%f ",m[i][j]);
  329.         printf("\n");
  330.     }
  331. }
  332. printvect(s, v)
  333.     char    *s;
  334.     Vector v;
  335. {
  336.     printf("%s %f %f %f %f\n", s, v[0], v[1], v[2], v[3]);
  337. }
  338.  
  339. #endif
  340.